﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MemoryStreamTest
{
    class Program
    {
        //static void Main(string[] args)
        //{
        //    MemoryStream memoryStream = new MemoryStream();
        //    Console.WriteLine($"初始分配容量为:{memoryStream.Capacity}");
        //    Console.WriteLine($"初始长度为:{memoryStream.Length}");

        //    //UnicodeEncoding encoder = new UnicodeEncoding();
        //    //byte[] bytes = encoder.GetBytes("hello");

        //    //byte[] bytes = Encoding.Default.GetBytes("hello");
        //    //byte[] bytes = Encoding.ASCII.GetBytes("hello");
        //    byte[] bytes = Encoding.Unicode.GetBytes("hello");

        //    memoryStream.Write(bytes, 0, bytes.Length);
        //    Console.WriteLine($"当前分配容量为:{memoryStream.Capacity}");
        //    Console.WriteLine($"当前长度为:{memoryStream.Length}");
        //    Console.WriteLine($"当前偏移位置：{memoryStream.Position}");

        //    //memoryStream.Seek(3, SeekOrigin.End);
        //    //memoryStream.Seek(3, SeekOrigin.Current);
        //    memoryStream.Seek(3, SeekOrigin.Begin);
        //    Console.WriteLine($"偏移后游标位置：{memoryStream.Position}");
        //    Console.WriteLine($"偏移后分配容量为:{memoryStream.Capacity}");
        //    Console.WriteLine($"偏移后长度为:{memoryStream.Length}");

        //    Console.ReadKey();
        //}

        //static void Main(string[] args)
        //{
        //    int count;
        //    byte[] byteArray;
        //    char[] charArray;
        //    UnicodeEncoding uniEncoding = new UnicodeEncoding();

        //    byte[] firstString = uniEncoding.GetBytes(
        //        "Invalid file path characters ares:");
        //    byte[] secondString = uniEncoding.GetBytes(
        //        Path.GetInvalidPathChars());

        //    using (MemoryStream memStream = new MemoryStream(100))
        //    {
        //        memStream.Write(firstString, 0, firstString.Length);

        //        count = 0;
        //        while (count < secondString.Length)
        //        {
        //            memStream.WriteByte(secondString[count++]);
        //        }

        //        Console.WriteLine($"Capacity = {memStream.Capacity},Length = {memStream.Length}, Position = {memStream.Position}");

        //        memStream.Seek(0, SeekOrigin.Begin);

        //        byteArray = new byte[memStream.Length];
        //        count = memStream.Read(byteArray, 0, 20);

        //        while (count < memStream.Length)
        //        {
        //            byteArray[count++] =
        //                Convert.ToByte(memStream.ReadByte());
        //        }

        //        charArray = new char[uniEncoding.GetCharCount(byteArray, 0, count)];
        //        uniEncoding.GetDecoder().GetChars(byteArray, 0, count, charArray, 0);
        //        Console.WriteLine(charArray);
        //    }
        //    Console.ReadKey();
        //}

        //static void Main(string[] args)
        //{
        //    MemoryStream ms = new MemoryStream();
        //    Console.WriteLine(ms.CanRead);
        //    Console.WriteLine(ms.CanSeek);
        //    Console.WriteLine(ms.CanTimeout);
        //    Console.WriteLine(ms.CanWrite);

        //    Console.WriteLine(ms.Capacity);

        //    byte[] bytes = Encoding.UTF8.GetBytes("abcdedcba");
        //    ms.Write(bytes, 0, bytes.Length);
        //    Console.WriteLine(ms.Capacity);
        //    Console.WriteLine(ms.Length);
        //    Console.WriteLine(ms.Position);

        //    //Console.WriteLine(ms.ReadTimeout);
        //    //Console.WriteLine(ms.WriteTimeout)

        //    byte[] byte1 = ms.GetBuffer();
        //    string str1 = Encoding.UTF8.GetString(byte1);
        //    Console.WriteLine($"str1: {str1}");
        //    Console.WriteLine(byte1.Length);
        //    Console.WriteLine(str1.Length);

        //    ms.Seek(2, SeekOrigin.Begin);
        //    int i = ms.ReadByte();
        //    Console.WriteLine(i);
        //    byte[] bytes3 = ms.ToArray();
        //    Console.WriteLine($"bytes3.Lenght: {bytes3.Length}");
        //    Console.WriteLine($"ms.Length:{ms.Length}");
        //    foreach (byte b in bytes3)
        //    {
        //        Console.Write(b + "-");
        //    }
        //    Console.WriteLine();

        //    MemoryStream ms2 = new MemoryStream();
        //    byte[] bytes6 = Encoding.UTF8.GetBytes("abcde");
        //    ms2.Write(bytes6, 0, bytes6.Length);
        //    //ms2.Write(bytes6, 4, 1);
        //    Console.WriteLine(ms2.Position);
        //    Console.WriteLine(Encoding.UTF8.GetString(ms2.ToArray()));
        //    ms2.Seek(0, SeekOrigin.Begin);
        //    ms2.Position = 0;

        //    byte[] byteArray = new byte[7] { 110, 110, 110, 110, 110, 110, 110 };

        //    ms2.Read(byteArray, 2, 1);
        //    Console.WriteLine(Encoding.UTF8.GetString(byteArray));
        //    ms2.Read(byteArray, 2, 5);
        //    Console.WriteLine(Encoding.UTF8.GetString(byteArray));

        //    Console.WriteLine(ms.Length);
        //    ms.SetLength(20);
        //    Console.WriteLine(ms.Length);
        //    Console.WriteLine($"当前ms的capacity:{ms.Capacity}");
        //    foreach (byte b in ms.ToArray())
        //    {
        //        Console.Write(b + "-");
        //    }
        //    Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
        //    Console.WriteLine($"改变length后读取数据的长度为：{ms.ToArray().Length}");

        //    MemoryStream ms1 = new MemoryStream();
        //    byte[] bytes4 = ms1.ToArray();
        //    Console.WriteLine($"内存流没有数据 {Encoding.UTF8.GetString(bytes4)}");

        //    MemoryStream ms3 = new MemoryStream();
        //    byte[] bytesArr = Encoding.ASCII.GetBytes("abcdefg");
        //    ms3.Write(bytesArr, 0, bytesArr.Length);
        //    ms3.Position = 2;
        //    ms3.WriteByte(97);
        //    string str = Encoding.ASCII.GetString(ms3.ToArray());
        //    Console.WriteLine(str);

        //    byte[] byteArr1 = Encoding.ASCII.GetBytes("kk");
        //    ms3.Position = 4;
        //    ms3.Write(byteArr1, 0, byteArr1.Length);
        //    Console.WriteLine(Encoding.UTF8.GetString(ms3.ToArray()));

        //    Console.ReadKey();
        //}


        //static void Main(string[] args)
        //{
        //    string text = "abc\nabc";

        //    using (TextReader reader = new StringReader(text))
        //    {
        //        while (reader.Peek() != -1)
        //        {
        //            Console.WriteLine($"Peek = { (char)reader.Peek()}");
        //            Console.WriteLine($"Read = {(char)reader.Read()}");
        //        }
        //        reader.Close();
        //    }

        //    using (TextReader reader = new StringReader(text))
        //    {
        //        char[] charBuffer = new char[3];
        //        int data = reader.ReadBlock(charBuffer, 0, 3);
        //        for (int i = 0; i < charBuffer.Length; i++)
        //        {
        //            Console.WriteLine($"通过readBlock读出的数据：{charBuffer[i]}");
        //        }
        //        reader.Close();
        //    }

        //    using (TextReader reader = new StringReader(text))
        //    {
        //        string allData = reader.ReadToEnd();
        //        Console.WriteLine($"全部的数据为：{allData}");
        //    }

        //    Console.ReadKey();

        //}

        //static void Main(string[] args)
        //{
        //    //FileStream fs = new FileStream("C:\\TestReader\\TextReader.txt", FileMode.Open, FileAccess.Read);
        //    //StreamReader sr = new StreamReader(fs);
        //    //sr.BaseStream.Seek(0, SeekOrigin.Begin);

        //    string txtFilePath = "C:\\TestReader\\TextReader.txt";
        //    char[] charBuffer2 = new char[3];

        //    using (FileStream stream = File.OpenRead(txtFilePath))
        //    {
        //        using (StreamReader reader = new StreamReader(stream))
        //        {
        //            DisplayResultStringByUsingRead(reader);
        //        }
        //    }

        //    using (FileStream stream = File.OpenRead(txtFilePath))
        //    {
        //        using (StreamReader reader = new StreamReader(stream, Encoding.ASCII, false))
        //        {
        //            DisplayResultStringByUsingReadBlock(reader);
        //        }
        //    }

        //    using (StreamReader reader = new StreamReader(txtFilePath, Encoding.Default, false, 123))
        //    {
        //        Console.WriteLine($"当前编码为：{Encoding.Default.GetType().Name}");
        //        DisplayResultStringByUsingReadLine(reader);
        //    }

        //    using (StreamReader reader = File.OpenText(txtFilePath))
        //    {
        //        DisplayResultStringByUsingReadLine(reader);
        //    }

        //    Console.ReadLine();
        //}

        //public static void DisplayResultStringByUsingRead(StreamReader reader)
        //{
        //    int readChar = 0;
        //    string result = string.Empty;
        //    while ((readChar = reader.Read()) != -1)
        //    {
        //        result += (char)readChar;
        //    }
        //    Console.WriteLine($"使用StreamReader.Read()方法得到Text文件中的数据位：{result}");
        //}

        //public static void DisplayResultStringByUsingReadBlock(StreamReader reader)
        //{
        //    char[] charBuffer = new char[10];
        //    string result = string.Empty;
        //    reader.ReadBlock(charBuffer, 0, 10);
        //    for (int i = 0; i < charBuffer.Length; i++)
        //    {
        //        result += charBuffer[i];
        //    }
        //    Console.WriteLine($"使用StreamReader.ReadBlock()方法得到Text文件中前10个数据为：{result}");
        //}

        //public static void DisplayResultStringByUsingReadLine(StreamReader reader)
        //{
        //    int i = 1;
        //    string resultString = string.Empty;
        //    while ((resultString = reader.ReadLine()) != null)
        //    {
        //        Console.WriteLine($"使用StreamReader.ReadLine()方法得到Text文件中第{i++}行的数据为：{resultString}");
        //    }
        //}

        //static void Main(string[] args)
        //{
        //    string txtFilePath = "C:\\TestReader\\TextWriter.txt";
        //    NumberFormatInfo numberFormatProvier = new NumberFormatInfo();
        //    numberFormatProvier.PercentDecimalSeparator = "?";
        //    StreamWriterTest test = new StreamWriterTest(Encoding.Default, txtFilePath, numberFormatProvier);

        //    test.WriteSomethingToFile();
        //    test.WriteSomethingToFileByUsingTextWriter();

        //    Console.ReadLine();
        //}

        static void Main(string[] args)
        {
            //Server server = new Server("http://www.163.com/");
            //server.FetchWebPageData();
            byte[] mBuffer = new byte[1024 * 1024];
            string value = "111111111";
            string value1 = "2222222222222222";
            MemoryStream stream = new MemoryStream(mBuffer);
            Console.WriteLine("Capacity: " + stream.Capacity);
            Console.WriteLine("Length: " + stream.Length);
            Console.WriteLine("Position: " + stream.Position);

            int count = Encoding.UTF8.GetBytes(value, 0, value.Length, mBuffer, 0);
            stream.Position = 0;
            stream.SetLength(count);
            Console.WriteLine("mBuffer Length: " + mBuffer.Length);
            Console.WriteLine(Encoding.UTF8.GetString(mBuffer, 0, count));
            Console.WriteLine($"GetString(mBuffer) Length: {Encoding.UTF8.GetString(mBuffer, 0, count).Length}");

            Console.WriteLine("Capacity: " + stream.Capacity);
            Console.WriteLine("Length: " + stream.Length);
            Console.WriteLine("Position: " + stream.Position);

            count = Encoding.UTF8.GetBytes(value1, 0, value1.Length, mBuffer, 0);
            Console.WriteLine(Encoding.UTF8.GetString(mBuffer, 0, count));

            stream.Position = 0;
            stream.SetLength(count);
            Console.WriteLine("stream Length: " + stream.Length);
            Console.WriteLine("count: " + count);
            Console.WriteLine(Encoding.UTF8.GetString(mBuffer, 0, count));

            Console.ReadKey();
        }

    }

    public class StreamWriterTest
    {
        private Encoding _encoding;

        private IFormatProvider _provier;

        private string _textFilePath;

        public StreamWriterTest(Encoding encoding, string textFilePath) : this(encoding, textFilePath, null)
        {
        }

        public StreamWriterTest(Encoding encoding, string textFilePath, IFormatProvider provider)
        {
            this._encoding = encoding;
            this._textFilePath = textFilePath;
            this._provier = provider;
        }

        public void WriteSomethingToFile()
        {
            using (FileStream stream = File.OpenWrite(_textFilePath))
            {
                using (StreamWriter writer = new StreamWriter(stream, this._encoding))
                {
                    this.WriteSomethingToFile(writer);
                }
            }
        }

        public void WriteSomethingToFile(StreamWriter writer)
        {
            string[] writerMethodOverloadType =
            {
                "1.Write(bool);",
                "2.Write(char);",
                "3.Write(char[])",
                "4.Write(Decimal)",
                "5.Write(Double)",
                "6.Write(Int32)",
                "7.Write(Int64)",
                "8.Write(Object)",
                "9.Write(Char[])",
                "10.Write(Char[])",
                "11.Write(Char[])",
                "12.Write(String)",
                "13Write(UInt32)",
                "14.Write(string format,obj)",
                "15.Write(Char[])"
            };

            writer.AutoFlush = true;
            writer.WriteLine($"这个StreamWriter使用了{writer.Encoding.HeaderName}编码");

            writerMethodOverloadType.ToList().ForEach
                (
                    (name) => { writer.WriteLine(name); }
                );
            writer.WriteLine("StreamWriter.WriteLine()方法就是加上行结束符,其它一样");
            writer.Close();
        }

        public void WriteSomethingToFileByUsingTextWriter()
        {
            using (TextWriter writer = new StringWriter(_provier))
            {
                writer.WriteLine($"设置了IFomatProvier {0.12:p10}");
                Console.WriteLine(writer.ToString());
                writer.Flush();
                writer.Close();
            }
        }

    }

    public class Server
    {
        const int webPort = 90;
        byte[] receiveBufferBytes = new byte[4096];
        private string webPageURL;
        public Server(string webPageUrl)
        {
            webPageURL = webPageUrl;
        }

        public void FetchWebPageData()
        {
            if (!string.IsNullOrEmpty(webPageURL))
                FetchWebPageData(webPageURL);
            Console.ReadLine();
        }

        private void FetchWebPageData(string webPageURL)
        {
            IPHostEntry iphe = Dns.GetHostEntry(GetHostNameBystrUrl(webPageURL));
            Console.WriteLine($"HostName : {GetHostNameBystrUrl(webPageURL)}");
            Console.WriteLine($"远程服务器名: {iphe.HostName}");

            IPAddress[] address = iphe.AddressList;
            IPEndPoint ipep = new IPEndPoint(address[0], 80);
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socket.Connect(ipep);
            if (socket.Connected)
            {
                socket.Send(Encoding.ASCII.GetBytes(this.GetHeader(webPageURL)));
            }
            else
            { return; }

            var count = socket.Receive(receiveBufferBytes);
            var getString = Encoding.Default.GetString(receiveBufferBytes);
            FileStream fs = new FileStream(@"d:\\Test.html", FileMode.OpenOrCreate);
            BufferedStream bs = new BufferedStream(fs);
            using (fs)
            {
                byte[] finalContent = Encoding.Default.GetBytes(getString.ToCharArray());
                bs.Write(finalContent, 0, finalContent.Length);
                while (count > 0)
                {
                    count = socket.Receive(receiveBufferBytes, receiveBufferBytes.Length, SocketFlags.None);
                    bs.Write(receiveBufferBytes, 0, receiveBufferBytes.Length);
                    Console.WriteLine(Encoding.Default.GetString(receiveBufferBytes));
                }
                bs.Flush();
                fs.Flush();
                bs.Close();
                fs.Close();
            }

        }

        private string GetHeader(string webPageurl)
        {
            return "GET " + GetRelativeUrlBystrUrl(webPageurl) + " HTTP/1.1r\nHost: " +
                GetHostNameBystrUrl(webPageURL) + "\r\nConnection:Close\r\n\r\n";
        }

        private string GetRelativeUrlBystrUrl(string strUrl)
        {
            int iIndex = strUrl.IndexOf(@"//");
            if (iIndex <= 0)
                return "/";
            string strTemp = strUrl.Substring(iIndex + 2);
            iIndex = strTemp.IndexOf(@"/");
            if (iIndex > 0)
                return strTemp.Substring(iIndex);
            else
                return "/";
        }

        private string GetHostNameBystrUrl(string strUrl)
        {
            int iIndex = strUrl.IndexOf(@"//");
            if (iIndex <= 0)
                return "";
            string strTemp = strUrl.Substring(iIndex + 2);
            iIndex = strTemp.IndexOf(@"/");
            if (iIndex > 0)
                return strTemp.Substring(0, iIndex);
            else
                return strTemp;
        }
    }
}
